from microbit import *
import coroutine

Camera_Add = 0x14

Card = 2
Face = 6
Ball = 7
ColorAI = 9
Learn = 10

numberCards = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
letterCards = ["A", "B", "C", "D", "E"]
otherCards = ["Mouse", "micro:bit", "Ruler", "Cat", "Peer", "Ship", "Apple", "Car", "Pan", "Dog", "Umbrella",
              "Airplane", "Clock", "Grape", "Cup", "Turn left", "Turn right", "Forward", "Stop", "Back"]
colorList = ["Green", "Blue", "Yellow", "Black", "Red", "White"]

# 错误标志
ERR = -1

Camera_Mode = Card
Camera_Success = 0
count = 0


def i2c_w(addr, d):
    global Camera_Success
    try:
        return i2c.write(addr, d)
    except:
        Camera_Success = 0
        pass


class AILENS(object):
    def __init__(self):
        global Camera_Fail
        self.recursion_depth = 0
        self.__DBF = [0, 0, 0, 0, 0, 0, 0, 0, 0]
        self.__Temp_Data_buff = [0, 0, 0, 0, 0, 0, 0, 0, 0]
        try:
            i2c.init()
            sleep(5000)
            i2c.read(Camera_Add, 1)
        except:
            pass

    def switch_function(self, func):
        global Camera_Mode, Camera_Success
        Camera_Mode = func
        try:
            i2c.write(Camera_Add, bytearray([0x20, func]))
            Camera_Success = 1
        except:
            Camera_Success = 0
            pass

    def get_image(self):
        global Camera_Success

        # 先检查是否有事件
        coroutine.handle_logo()

        devices = i2c.scan()
        if 20 not in devices:
            print('no camera')
            sleep(1500)
            Camera_Success = 0
            return
        if Camera_Success == 0:
            try:
                data = i2c.read(Camera_Add, 9)
                arr = bytearray(data)
                if arr[0] and arr[0] == 2:
                    self.switch_function(Camera_Mode)
            except:
                pass
            return

        self.__Temp_Data_buff = i2c.read(Camera_Add, 9)
        if self.__Temp_Data_buff == self.__DBF:
            sleep(50)
            if self.recursion_depth < 5:
                self.recursion_depth = self.recursion_depth + 1
                self.get_image()
        else:
            self.__DBF = self.__Temp_Data_buff
            sleep(80)

    def get_ball_data(self, index=-1):
        BallData = []
        for i in range(7):
            BallData.append(self.__DBF[i + 2])
        if index >= 0:
            return BallData[index]
        return BallData

    def get_ball_amount(self):
        return self.get_ball_data(5)

    def get_ball_color(self):
        if self.__DBF[0] == 7:
            if self.__DBF[1] == 1:
                return "Blue"
            elif self.__DBF[1] == 2:
                return "Red"
        return ERR

    def image_has_ball(self):
        r = self.get_ball_data()
        return True if r[5] > 0 else False

    def image_has_color_ball(self, color):
        return color == self.get_ball_color()

    def get_face(self):
        return self.__DBF[0] == 6

    def get_face_data(self, index=-1):
        FaceData = []
        for i in range(7):
            FaceData.append(self.__DBF[i + 2])
        if index >= 0:
            return FaceData[index]
        return FaceData

    def get_face_amount(self):
        return self.get_face_data(5)

    def get_card_content(self):
        if self.__DBF[0] == 2:
            return numberCards[self.__DBF[1] - 1]
        elif self.__DBF[0] == 4:
            return letterCards[self.__DBF[1] - 1]
        elif self.__DBF[0] == 3 and self.__DBF[1] < 21:
            return otherCards[self.__DBF[1] - 1]
        return ERR

    def get_card_data(self, index=-1):
        CardData = []
        for i in range(7):
            CardData.append(self.__DBF[i + 2])
        if index >= 0:
            return CardData[index]
        return CardData

    def get_card_amount(self):
        return self.get_card_data(5)

    def image_is_number(self, n):
        c = self.get_card_content()
        return str(c) == str(n)

    def image_is_traffic(self, s):
        if self.__DBF[0] == 3 and self.__DBF[1] < 21:
            return otherCards[self.__DBF[1] - 1] == s
        return False

    def get_color_type(self):
        if self.__DBF[0] == 9:
            return colorList[self.__DBF[1] - 1]
        return ERR

    def get_color_data(self, index=-1):
        ColorData = []
        for i in range(7):
            ColorData.append(self.__DBF[i + 2])
        if index >= 0:
            return ColorData[index]
        return ColorData

    def image_is_color(self, c):
        return self.get_color_type() == c

    def learn_object(self, learn_id):
        i2c_w(Camera_Add, bytearray([10, learn_id]))
        sleep(200)

    def get_learn_data(self):
        LearnData = [self.__DBF[1], 100 - self.__DBF[2]]
        return LearnData

    # 图像包含
    def image_contain_object(self, id):
        buff = self.get_learn_data()
        if id == buff[0] and buff[1] > 85:
            return True
        return False

    # 清空学习
    def clear_learn_data(self):
        i2c_w(Camera_Add, bytearray([10, 10]))

    # 获取置信度
    def get_object_confidence(self, id):
        sleep(60)
        buff = self.get_learn_data()
        if id == buff[0]:
            return buff[1]
        return 0


alien = AILENS()